<script lang="ts">
	export let data;
	import { knowledge1, storageFiles } from "$lib/shared/stores/common/Store";
	import { onMount } from "svelte";
	import {
		LOCAL_STORAGE_KEY,
		MessageRole,
		MessageType,
		type Message,
	} from "$lib/shared/constant/Interface";
	import {
		getCurrentTimeStamp,
		scrollToBottom,
		scrollToTop,
	} from "$lib/shared/Utils";
	import { fetchTextStream } from "$lib/network/chat/Network"; // 引入后端交互函数
	import LoadingAnimation from "$lib/shared/components/loading/Loading.svelte";
	import "driver.js/dist/driver.css";
	import "$lib/assets/layout/css/driver.css";
	import UploadFile from "$lib/shared/components/upload/uploadFile.svelte";
	import PaperAirplane from "$lib/assets/chat/svelte/PaperAirplane.svelte";
	import Scrollbar from "$lib/shared/components/scrollbar/Scrollbar.svelte";
	import ChatMessage from "$lib/modules/chat/ChatMessage.svelte";
	import { fetchAllFile } from "$lib/network/upload/Network.js";
	import { getNotificationsContext } from "svelte-notifications";
	import { goto } from "$app/navigation";

	let query: string = "";
	let loading = false; // 控制加载状态
	let scrollToDiv: HTMLDivElement; // 聊天框滚动元素
	let chatMessages: Message[] = data.chatMsg ? data.chatMsg : [];
	const { addNotification } = getNotificationsContext(); // 获取通知上下文
	let isSidebarOpen = false; // 控制侧边栏的打开和关闭
	let isTyping = false; // 控制是否显示打字机效果
	$: knowledge_1 = $knowledge1?.id ? $knowledge1.id : "default";

	// 页面加载时获取文件
	onMount(async () => {
		// sessionStorage.setItem("msg_key", accmulatedMsg);
		scrollToDiv = document
			.querySelector(".chat-scrollbar")
			?.querySelector(".svlr-viewport")!;

		const res = await fetchAllFile();
		if (res) {
			storageFiles.set(res);
		}
	});

	// 显示通知
	function showNotification(text: string, type: string) {
		addNotification({
			text: text,
			position: "top-left",
			type: type,
			removeAfter: 3000,
		});
	}

	function handleTop() {
		scrollToTop(scrollToDiv);
	}

	function storeMessages() {
		localStorage.setItem(
			LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY,
			JSON.stringify(chatMessages)
		);
	}

	function decodeEscapedBytes(str: string): string {
		const byteArray = str
			.split("\\x")
			.slice(1)
			.map((byte) => parseInt(byte, 16));
		const decoded = new TextDecoder("utf-8").decode(new Uint8Array(byteArray));

		return decoded;
	}

	function decodeUnicode(str: string): string {
		const decoded = str.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
			return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
		});

		return decoded;
	}

	// 处理发送消息
	const handleTextSubmit = async () => {
		loading = true;

		// 清空之前的累积消息
		sessionStorage.removeItem("msg_key");

		const newMessage = {
			role: MessageRole.User,
			type: MessageType.Text,
			content: query,
			time: 0,
		};
		chatMessages = [...chatMessages, newMessage];
		scrollToBottom(scrollToDiv);
		storeMessages();
		query = "";

		await callTextStream(newMessage.content, getCurrentTimeStamp());

		scrollToBottom(scrollToDiv);
		storeMessages();
	};

	// 通过流式接口获取聊天内容
	const callTextStream = async (query: string, startSendTime: number) => {
		try {
			const eventSource = await fetchTextStream(query);
			eventSource.addEventListener("error", (e: any) => {
				if (e.type === "error") {
					showNotification("Failed to load chat content.", "error");
					loading = false;
				}
			});

			eventSource.addEventListener("message", (e: any) => {
				let msg = e.data;
				console.log("msg", msg);

				// Accumulate messages in sessionStorage
				let accumulatedMsg = sessionStorage.getItem("msg_key") || ""; // Get existing messages or start with an empty string
				accumulatedMsg += msg; // Append the new message
				sessionStorage.setItem("msg_key", accumulatedMsg); // Save the accumulated content
				console.log("acc", accumulatedMsg);
				const handleDecodedMessage = (decodedMsg: string) => {
					if (decodedMsg !== "</s>") {
						decodedMsg = decodedMsg.replace(/\\n/g, "\n");
					}

					if (chatMessages[chatMessages.length - 1].role === MessageRole.User) {
						chatMessages.push({
							role: MessageRole.Assistant,
							type: MessageType.Text,
							content: decodedMsg,
							time: startSendTime,
						});
					} else {
						chatMessages[chatMessages.length - 1].content += decodedMsg;
					}

					scrollToBottom(scrollToDiv);
				};

				if (msg.startsWith("b")) {
					let currentMsg = msg.slice(2, -1);

					if (/\\x[\dA-Fa-f]{2}/.test(currentMsg)) {
						currentMsg = decodeEscapedBytes(currentMsg);
					} else if (/\\u[\dA-Fa-f]{4}/.test(currentMsg)) {
						currentMsg = decodeUnicode(currentMsg);
					}

					handleDecodedMessage(currentMsg);
				} else if (msg === "[DONE]") {
					console.log("Done");

					let startTime = chatMessages[chatMessages.length - 1].time;
					loading = false;
					let totalTime = parseFloat(
						((getCurrentTimeStamp() - startTime) / 1000).toFixed(2)
					);

					if (chatMessages.length - 1 !== -1) {
						chatMessages[chatMessages.length - 1].time = totalTime;
					}

					// 清空累积消息
					sessionStorage.removeItem("msg_key");

					storeMessages();
				} else {
					if (/\\x[\dA-Fa-f]{2}/.test(msg)) {
						msg = decodeEscapedBytes(msg);
					} else if (/\\u[\dA-Fa-f]{4}/.test(msg)) {
						msg = decodeUnicode(msg);
					}

					let currentMsg = msg.replace(/"/g, "").replace(/\\n/g, "\n");

					handleDecodedMessage(currentMsg);
				}
			});

			eventSource.stream();
		} catch (error: any) {
			showNotification("Failed to load chat content.", "error");
			loading = false;
		}
	};

	function handelClearHistory() {
		localStorage.removeItem(LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY);
		chatMessages = [];
	}

	// 处理键盘按下事件，支持 Enter 键发送消息
	const handleKeydown = (event: KeyboardEvent) => {
		if (event.key === "Enter") {
			event.preventDefault(); // 阻止默认行为（例如换行）
			handleTextSubmit(); // 触发发送消息的逻辑
		}
	};
</script>

<!-- Main layout -->
<div class="flex h-full">
	<!-- Sidebar -->
	<div class="fixed left-0 top-0 h-full w-64 bg-gray-800 text-white">
		<div class="p-4">
			<h2 class="mb-6 text-2xl font-bold">Sidebar</h2>
			<ul class="space-y-4">
				<li>
					<button
						on:click={() => goto("/mermaid")}
						class="w-full rounded-lg bg-gray-700 px-4 py-2 text-left text-lg font-semibold transition-all duration-200 ease-in-out hover:bg-gray-600 focus:bg-gray-600 active:bg-gray-500"
					>
						Go to Mermaid
					</button>
				</li>
				<li>
					<button
						on:click={() => goto("/drawer")}
						class="w-full rounded-lg bg-gray-700 px-4 py-2 text-left text-lg font-semibold transition-all duration-200 ease-in-out hover:bg-gray-600 focus:bg-gray-600 active:bg-gray-500"
					>
						Go to Drawer
					</button>
				</li>
			</ul>
		</div>
	</div>

	<!-- Main content -->
	<div class="main-content ml-64 flex flex-1 flex-col p-4">
		<!-- Use padding-left to avoid sidebar overlap -->
		<div class="fixed right-0 top-0 z-10 p-4">
			<!-- Removed button for controlling the sidebar -->
		</div>

		<!-- Chat display area -->
		<div class="flex-1 overflow-auto rounded-lg bg-white p-4">
			<div class="flex flex-col gap-4">
				<div class="flex justify-between p-2">
					<p class="text-[1.7rem] font-bold tracking-tight">Drawer</p>
					<!-- <button on:click={() => goto("/mermaid")}>View Mermaid Diagram</button> -->
				</div>

				<!-- Chat messages -->
				<div
					class="flex flex-col gap-2 overflow-auto"
					style="height: 620px;overflow: auto; font-size:1.1em;"
				>
					{#each chatMessages as message, i}
						<ChatMessage
							on:scrollTop={() => handleTop()}
							msg={message}
							style="font-size: 1.5em;"
							class="text-2xl"
						/>
					{/each}
					<p>{chatMessages.length} messages in total</p>
				</div>

				<!-- Loading animation -->
				<div
					style="height: 50px; display: flex; align-items: center; justify-content: center;"
				>
					{#if loading}
						<div class="spinner" />
					{/if}
				</div>
				<!-- Chat input box -->
				<div class="mt-4 flex gap-2">
					<input
						type="text"
						class="flex-1 rounded border p-2"
						bind:value={query}
						placeholder="Type your message..."
						on:keydown={handleKeydown}
					/>
					<button
						class="rounded bg-blue-500 p-2 text-white"
						on:click={() => {
							if (query) {
								handleTextSubmit();
							}
						}}
						type="submit"
						id="send"
					>
						<PaperAirplane />
					</button>
				</div>
			</div>
		</div>
	</div>
</div>

<style>
	.spinner {
		border: 4px solid #f3f3f3; /* 背景圆圈 */
		border-top: 4px solid #3498db; /* 旋转部分的颜色 */
		border-radius: 50%;
		width: 20px;
		height: 20px;
		animation: spin 1s linear infinite;
	}

	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}
	
	button {
		background-color: #007bff;
		color: white;
		padding: 10px 20px;
		border: none;
		border-radius: 5px;
		cursor: pointer;
	}

	button:hover {
		background-color: #0056b3;
	}
	.transition-transform {
		transition: transform 0.3s ease-in-out;
	}
	.main-content {
		margin-left: 264px; /* 侧边栏宽度 + 8px的额外空间 */
		padding: 16px;
		height: 100%;
		overflow: auto;
	}
	
</style>
